home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue54 / Persist / tiPerObjAbs.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2000-01-21  |  7.7 KB  |  228 lines

  1. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2.   (c) TechInsite Pty. Ltd.
  3.   PO Box 429, Abbotsford, Melbourne. 3067 Australia
  4.   Phone: +61 3 9419 6456
  5.   Fax:   +61 3 9419 1682
  6.   Web:   www.techinsite.com.au
  7.   EMail: peter_hinrichsen@techinsite.com.au
  8.  
  9.   Created: Jan 2000
  10.  
  11.   Notes: Abstract persistant base classes
  12.  
  13. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  14. unit tiPerObjAbs;
  15.  
  16. interface
  17. uses
  18.   tiPtnVisitor
  19.   ;
  20.  
  21. type
  22.   // The possible states a persistent object can be in:
  23.   TPersistentObjectState = ( posCreate,  // The object is new and must be created in the DB
  24.                              posRead,    // The object has been created, but not filled with data from the DB
  25.                              posPK,      // The object has been created, but only it's primary key has been read
  26.                              posUpdate,  // The object has been changed, the DB must be updated
  27.                              posDelete,  // The object has been deleted, it must be deleted from the DB
  28.                              posDeleted, // The object was marked for deletion, and has been deleted in the database
  29.                              posClean    // The object is 'Clean' no DB update necessary
  30.                            ) ;
  31.  
  32.   // Abstract base persistent object
  33.   //----------------------------------------------------------------------------
  34.   TPerObjAbs = class( TVisitedAbs )
  35.   private
  36.     FIntOID : integer ;
  37.     FObjectState : TPersistentObjectState ;
  38.     FIntDispOrder : integer ;
  39.     FOwner: TPerObjAbs;
  40.     function  GetDeleted: boolean;
  41.     procedure SetDeleted(const Value: boolean);
  42.     function  GetDirty: boolean;
  43.     procedure SetDirty(const Value: boolean);
  44.   protected
  45.     procedure SetOID(const Value: integer); virtual ;
  46.   public
  47.     // Create, and set ObjectState to posClean
  48.     constructor Create ; override ;
  49.     // Create, and assing a new OID
  50.     constructor CreateNew ; virtual ;
  51.     // The object's OID
  52.     property    OID : integer                        read FIntOID       write SetOID ;
  53.     // The objects display order, when the object is contained in an ordered list.
  54.     property    DispOrder : integer                  read FIntDispOrder write FIntDispOrder ;
  55.     // The object's state: ie, clean, update, deleted, etc
  56.     property    ObjectState : TPersistentObjectState read FObjectState  write FObjectState ;
  57.     // An optional back pointer to the owner of the object
  58.     property    Owner       : TPerObjAbs             read FOwner        write FOwner ;
  59.     // Has the object been marked as deleted?
  60.     property    Deleted : boolean                    read GetDeleted    write SetDeleted ;
  61.     // Is the object dirty? ie its state <> posClean
  62.     property    Dirty   : boolean                    read GetDirty      write SetDirty ;
  63.   end ;
  64.  
  65.   // A visitor to iterate through an object's owned objects, and mark them for
  66.   // deletion.
  67.   //----------------------------------------------------------------------------
  68.   TVisPerObjDel = class( TVisitorAbs )
  69.   protected
  70.     function    AcceptVisitor : boolean ; override ;
  71.   public
  72.     procedure   Execute( pVisited : TVisitedAbs ) ; override ;
  73.   end ;
  74.  
  75.   // Iterate over an object's owned objects and determine if any of its owned
  76.   // objects are dirty.
  77.   //----------------------------------------------------------------------------
  78.   TVisPerObjIsDirty = class( TVisitorAbs )
  79.   private
  80.     FbDirty: boolean;
  81.   protected
  82.     function    AcceptVisitor : boolean ; override ;
  83.   public
  84.     procedure   Execute( pVisited : TVisitedAbs ) ; override ;
  85.     property    Dirty : boolean read FbDirty write FbDirty ;
  86.   end ;
  87.  
  88. implementation
  89. uses
  90.   dbNextOID
  91.   ,Dialogs // Debug
  92.   ;
  93.  
  94. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  95. // *
  96. // * TPerObjAbs
  97. // *
  98. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  99. constructor TPerObjAbs.Create;
  100. begin
  101.   inherited ;
  102.   ObjectState := posClean ;
  103. end;
  104.  
  105. // Create a new instance and get a new OID
  106. //------------------------------------------------------------------------------
  107. constructor TPerObjAbs.CreateNew ;
  108. begin
  109.   Create ;
  110.   OID         := gNextOID.NextOID ;
  111.   DispOrder   := 0 ;
  112.   ObjectState := posCreate ;
  113. end;
  114.  
  115. // Has this object been marked for deletion?
  116. //------------------------------------------------------------------------------
  117. function TPerObjAbs.GetDeleted: boolean;
  118. begin
  119.   result := ( ObjectState = posDelete ) or
  120.             ( ObjectState = posDeleted ) ;
  121. end;
  122.  
  123. // Is this object diryt?
  124. //------------------------------------------------------------------------------
  125. function TPerObjAbs.GetDirty: boolean;
  126. var
  127.   lVis : TVisPerObjIsDirty ;
  128. begin
  129.   lVis := TVisPerObjIsDirty.Create ;
  130.   try
  131.     self.Iterate( lVis ) ;
  132.     result := lVis.Dirty ;
  133.   finally
  134.     lVis.Free ;
  135.   end ;
  136. end;
  137.  
  138. // Set all the owned object's state to posDelete
  139. //------------------------------------------------------------------------------
  140. procedure TPerObjAbs.SetDeleted(const Value: boolean);
  141. var
  142.   lVis : TVisPerObjDel ;
  143. begin
  144.   if Value and not Deleted then begin
  145.     lVis := TVisPerObjDel.Create ;
  146.     try
  147.       self.Iterate( lVis ) ;
  148.     finally
  149.       lVis.Free ;
  150.     end ;
  151.   end ;
  152. end;
  153.  
  154. // Set the object's state to posUpdate
  155. //------------------------------------------------------------------------------
  156. procedure TPerObjAbs.SetDirty(const Value: boolean);
  157. begin
  158.   if not ( ObjectState in
  159.      [ posCreate,  // The object is new and must be created in the DB
  160.        posUpdate,  // The object has been changed, the DB must be updated
  161.        posDelete  // The object has been deleted, it must be deleted from the DB
  162.      ]) then
  163.     FObjectState := posUpdate ;
  164. end;
  165.  
  166. // Set the OID
  167. //------------------------------------------------------------------------------
  168. procedure TPerObjAbs.SetOID(const Value: integer);
  169. begin
  170.   FIntOID := Value;
  171. end;
  172.  
  173. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  174. // *
  175. // * TVisPerObjDel
  176. // *
  177. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  178. // Only accept the visitor if ObjectState <> posDelete
  179. function TVisPerObjDel.AcceptVisitor : boolean;
  180. begin
  181.   result := ( Visited is TPerObjAbs ) and
  182.             ( TPerObjAbs( Visited ).ObjectState <> posDelete ) ;
  183. end;
  184.  
  185. // Set ObjectState to posDelete
  186. //------------------------------------------------------------------------------
  187. procedure TVisPerObjDel.Execute(pVisited: TVisitedAbs) ;
  188. begin
  189.   inherited Execute( pVisited ) ;
  190.  
  191.   if not AcceptVisitor then
  192.     exit ; //==>
  193.  
  194.   ( pVisited as TPerObjAbs ).ObjectState := posDelete ;
  195.  
  196. end;
  197.  
  198. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  199. // *
  200. // * TVisPerObjIsDirty
  201. // *
  202. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  203. // Only accept the visitor if the visitor's internal dirty flat is still false
  204. function TVisPerObjIsDirty.AcceptVisitor: boolean;
  205. begin
  206.   result := ( Visited is TPerObjAbs ) and
  207.             ( not Dirty ) ;
  208. end;
  209.  
  210. // Determine if an object is dirty
  211. //------------------------------------------------------------------------------
  212. procedure TVisPerObjIsDirty.Execute(pVisited: TVisitedAbs);
  213. begin
  214.   inherited Execute( pVisited ) ;
  215.  
  216.   if not AcceptVisitor then
  217.     exit ; //==>
  218.  
  219.   Dirty := TPerObjAbs( pVisited ).ObjectState in
  220.             [ posCreate,  // The object is new and must be created in the DB
  221.               posUpdate,  // The object has been changed, the DB must be updated
  222.               posDelete   // The object has been deleted, it must be deleted from the DB
  223.             ] ;
  224.  
  225. end;
  226.  
  227. end.
  228.